import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 日期格式化
 *
 * @author ZKL
 * @date 2018/7/3
 */
public class DateFormatUtils {
    /**
     * 格式化 {@value PATTERN_MINS}
     */
    public static final String PATTERN_MINS = "yyyy-MM-dd HH:mm";
    /**
     * 格式化 {@value PATTERN_DEFAULT}
     */
    public static final String PATTERN_DEFAULT = "yyyyMMddHHmmss";
    /**
     * 格式化 {@value PATTERN_MONTH}
     */
    public static final String PATTERN_MONTH = "yyyyMM";
    /**
     * 格式化 {@value PATTERN_SEC}
     */
    public static final String PATTERN_SEC = "yyyy-MM-dd HH:mm:ss";
    /**
     * 格式化 {@value PATTERN_UTC}
     */
    public static final String PATTERN_UTC = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
    /**
     * 格式化 {@value PATTERN_MINS}
     */
    public static final DateTimeFormatter FORMATTER_MINS = DateTimeFormatter.ofPattern(PATTERN_MINS);
    /**
     * 格式化 {@value PATTERN_SEC}
     */
    public static final DateTimeFormatter FORMATTER_SEC = DateTimeFormatter.ofPattern(PATTERN_SEC);
    /**
     * 格式化 {@value PATTERN_UTC}
     */
    public static final DateTimeFormatter FORMATTER_UTC = DateTimeFormatter.ofPattern(PATTERN_UTC);
    /**
     * 格式化 {@value PATTERN_DEFAULT}
     */
    public static final DateTimeFormatter FORMATTER_DEFAULT = DateTimeFormatter.ofPattern(PATTERN_DEFAULT);
    /**
     * 格式化 {@value PATTERN_MONTH}
     */
    public static final DateTimeFormatter FORMATTER_MONTH = DateTimeFormatter.ofPattern(PATTERN_MONTH);
    /**
     * 系统默认的时区
     */
    public static final ZoneId ZONE_ID_SYSTEM = ZoneId.systemDefault();

    /**
     * 格式化 {@value PATTERN_MINS}
     *
     * @param dateStr
     * @return
     */
    public static Date toDateMins(String dateStr) {
        return toDateTime(FORMATTER_MINS, ZONE_ID_SYSTEM, dateStr);
    }

    /**
     * 格式化 {@value PATTERN_SEC}
     *
     * @param dateStr
     * @return
     */
    public static Date toDateSec(String dateStr) {
        return toDateTime(FORMATTER_SEC, ZONE_ID_SYSTEM, dateStr);
    }

    /**
     * 格式化 {@value PATTERN_UTC} <br>
     * 使用使用的系统默认时区,并未使用UTC时区
     *
     * @param dateStr
     * @return
     */
    public static Date toDateUtc(String dateStr) {
        return toDateTime(FORMATTER_UTC, ZONE_ID_SYSTEM, dateStr);
    }

    /**
     * 格式化 {@value PATTERN_MINS}
     *
     * @param date
     * @return
     */
    public static String toStrMins(Date date) {
        return toString(FORMATTER_MINS, ZONE_ID_SYSTEM, date);
    }

    /**
     * 格式化 {@value PATTERN_UTC}
     *
     * @param date
     * @return
     */
    public static String toStrUtc(Date date) {
        return toString(FORMATTER_UTC, ZONE_ID_SYSTEM, date);
    }

    /**
     * 格式化 {@value PATTERN_SEC}
     *
     * @param date
     * @return
     */
    public static String toStrSec(Date date) {
        return toString(FORMATTER_SEC, ZONE_ID_SYSTEM, date);
    }

    /**
     * 格式化 {@value PATTERN_MONTH}
     *
     * @param date
     * @return
     */
    public static String toStrMonth(Date date) {
        return toString(FORMATTER_MONTH, ZONE_ID_SYSTEM, date);
    }

    /**
     * 字符串格式化成日期{@code java.util.Date}
     *
     * @param format
     * @param zoneId
     * @param dateStr
     * @return
     */
    public static Date toDateTime(DateTimeFormatter format, ZoneId zoneId, String dateStr) {
        if (format == null || zoneId == null || dateStr == null) {
            return null;
        }
        ZonedDateTime zdt = LocalDateTime.parse(dateStr, format).atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * 日期{@code java.util.Date} 格式化成字符串
     *
     * @param format
     * @param zoneId
     * @param date
     * @return
     */
    public static String toString(DateTimeFormatter format, ZoneId zoneId, Date date) {
        if (format == null || zoneId == null || date == null) {
            return null;
        }
        // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
        LocalDateTime localDateTime = date.toInstant().atZone(zoneId).toLocalDateTime();
        return localDateTime.format(format);
    }

    /**
     * 获取系统默认时间字符串<br/>
     * 格式化 {@value PATTERN_DEFAULT}
     *
     * @return
     */
    public static String getDateStrDefault() {
        return toString(FORMATTER_DEFAULT, ZONE_ID_SYSTEM, new Date());
    }
}
